package calendar.dan.com.calendar;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class KCalendar2 extends LinearLayout {
    public static final int COLOR_TX_THIS_MONTH_DAY = Color.parseColor("#ff564b4b"); // 当前月日历数字颜色
    public static final int COLOR_TX_OTHER_MONTH_DAY = Color.parseColor("#ffcccccc"); // 其他月日历数字颜色
    public static final int COLOR_TX_THIS_DAY = Color.parseColor("#ffffffff"); // 当天日历数字颜色
    public static final int COLOR_BG_THIS_DAY = R.drawable.day_bg; // 当天日历背景图片
    public static final int COLOR_BG_CALENDAR = Color.parseColor("#ffffff"); // 日历背景色
    private int ROWS_TOTAL = 6; // 日历的行数
    private int COLS_TOTAL = 7; // 日历的列数
    public String[][] dates = new String[6][7]; // 当前日历日期
    private OnCalendarClickListener onCalendarClickListener; // 日历翻页回调
    private int calendarYear; // 日历年份
    private int calendarMonth; // 日历月份
    private Date thisday; // 日期
    private Date today = new Date(); // 今天
    private Date calendarday; // 日历这个月第一天(1号)
    private Calendar calendar;
    private LinearLayout firstCalendar; // 第一个日历
    private LinearLayout currentCalendar; // 当前显示的日历
    private Map<String, Integer> marksMap = new HashMap<String, Integer>(); // 储存某个日子被标注(Integer
    private List<String> markList;
    private Map<String, Integer> dayBgColorMap = new HashMap<String, Integer>(); // 储存某个日子的背景色

    public KCalendar2(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    /**
     * 初始化
     * @param date  要显示哪个月的日期
     * @param markList 要做标记的日期
     */
    public void init(Calendar date, List<String> markList) {
        removeAllViews();  //无法刷新只能用笨办法了，特别是作为listView的item时,会重复显示，不能刷新
        calendar = date;
        this.markList = markList;
        this.thisday = date.getTime();
        addMarks(markList, R.drawable.day_bg_green);
        // 初始化第一个日历
        firstCalendar = new LinearLayout(getContext());
        firstCalendar.setOrientation(LinearLayout.VERTICAL);
        firstCalendar.setLayoutParams(new LinearLayout.LayoutParams(-1, -1));
        currentCalendar = firstCalendar;
        addView(firstCalendar);
        // 绘制线条框架
        drawFrame(firstCalendar);
        // 设置日历上的日子(1号)
        calendarYear = calendar.get(Calendar.YEAR);
        calendarMonth = calendar.get(Calendar.MONTH);
        calendarday = new Date(calendarYear - 1900, calendarMonth, 1);
        // 填充展示日历
        setCalendarDate();
    }

    private void drawFrame(LinearLayout oneCalendar) {
        LinearLayout content = new LinearLayout(getContext());
        content.setOrientation(LinearLayout.VERTICAL);
        content.setLayoutParams(new LinearLayout.LayoutParams(-1, 0, 7f));
        oneCalendar.addView(content);
        int weekNum = calendar.getActualMaximum(Calendar.WEEK_OF_MONTH); // 有几个星期
        ROWS_TOTAL = weekNum;
        // 绘制日历上的行
        for (int i = 0; i < ROWS_TOTAL; i++) {
            LinearLayout row = new LinearLayout(getContext());
            row.setOrientation(LinearLayout.HORIZONTAL);
            row.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, 0, 1));
            content.addView(row);
            // 绘制日历上的列
            for (int j = 0; j < COLS_TOTAL; j++) {
                RelativeLayout col = new RelativeLayout(getContext());
                col.setLayoutParams(new LinearLayout.LayoutParams(0, 150, 1));
                row.addView(col);
                // 给每一个日子加上监听
                col.setOnClickListener(new OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (v == currentDayView) {  //如果点击当天
                            return;
                        }
                        if (mClickDayView != null) {
                            mClickDayView.setBackgroundColor(Color.TRANSPARENT);
                            //	mClickDayView.setBackgroundResource(R.drawable.calendar_day_bg);
                        }
                        //                  	v.setBackgroundResource(R.drawable.day_bg_green);
                        if (((RelativeLayout) v).getChildAt(0) != null) {
                            ((RelativeLayout) v).getChildAt(0).setBackgroundResource(R.drawable.day_bg_green);
                            //                   	mClickDayView = v;
                            mClickDayView = ((RelativeLayout) v).getChildAt(0);
                        }
                        ViewGroup parent = (ViewGroup) v.getParent();
                        int row = 0, col = 0;
                        for (int i = 0; i < parent.getChildCount(); i++) {
                            if (v.equals(parent.getChildAt(i))) {
                                col = i;
                                break;
                            }
                        }
                        ViewGroup pparent = (ViewGroup) parent.getParent();
                        for (int i = 0; i < pparent.getChildCount(); i++) {
                            if (parent.equals(pparent.getChildAt(i))) {
                                row = i;
                                break;
                            }
                        }
                        if (onCalendarClickListener != null) {
                            onCalendarClickListener.onCalendarClick(row, col, dates[row][col]);
                        }
                    }
                });
            }
        }
    }

    private View mClickDayView;
    private View currentDayView;

    /**
     * 填充日历(包含日期、标记、背景等)
     */
    public void setCalendarDate() {
        // 根据日历的日子获取这一天是星期几
        int weekday = calendarday.getDay();
        // 每个月第一天
        int firstDay = 1;
        // 每个月中间号,根据循环会自动++
        int day = firstDay;
        // 每个月的最后一天
 //       int lastDay2 = getDateNum(calendarday.getYear(), calendarday.getMonth());
        int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        Log.i("999999999999999999","999999999999999lastDay==="+lastDay);
//        Log.i("999999999999999999","999999999999999lastDay2==="+lastDay2);
        // 下个月第一天
        int nextMonthDay = 1;
        int lastMonthDay = 1;
        // 填充每一个空格
        for (int i = 0; i < ROWS_TOTAL; i++) {
            for (int j = 0; j < COLS_TOTAL; j++) {
                // 这个月第一天不是礼拜天,则需要绘制上个月的剩余几天
                if (i == 0 && j == 0 && weekday != 0) {
                    int year = 0;
                    int month = 0;
                    int lastMonthDays = 0;
                    // 如果这个月是1月，上一个月就是去年的12月
                    if (calendar.get(Calendar.MONTH) == 0) {
                        year = calendar.get(Calendar.YEAR) - 1;
                        month = Calendar.DECEMBER;
                    } else {
                        year = calendar.get(Calendar.YEAR);
                        month = calendar.get(Calendar.MONTH) - 1;
                    }
                    // 上个月的最后一天是几号
                    lastMonthDays = getDateNum(year, month);
                    // 第一个格子展示的是几号
                    int firstShowDay = lastMonthDays - weekday + 1;
                    // 上月
                    for (int k = 0; k < weekday; k++) {
                        lastMonthDay = firstShowDay + k;
                        RelativeLayout group = getDateView(0, k);
                        group.setGravity(Gravity.CENTER);
                        TextView view = null;
                        if (group.getChildCount() > 0) {
                            view = (TextView) group.getChildAt(0);
                            view.setGravity(Gravity.CENTER);
                        } else {
                            //     RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(-1, -1);
                            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                            params.addRule(RelativeLayout.CENTER_IN_PARENT);
                            view = new TextView(getContext());
                            view.setGravity(Gravity.CENTER);
                            view.setLayoutParams(params);
                            //     group.addView(view);
                        }
                        view.setText(Integer.toString(lastMonthDay));
                        view.setTextColor(COLOR_TX_OTHER_MONTH_DAY);

                        dates[0][k] = format(new Date(year, month, lastMonthDay));
                        // 设置日期背景色
                        if (dayBgColorMap.get(dates[0][k]) != null) {
                            view.setBackgroundColor(dayBgColorMap.get(dates[0][k]));
                        } else {
                            view.setBackgroundColor(Color.TRANSPARENT);
                        }
                        // 设置标记
                        setMarker(group, 0, k);
                    }
                    j = weekday - 1;
                    // 这个月第一天是礼拜天，不用绘制上个月的日期，直接绘制这个月的日期
                } else {
                    // 本月
                    if (day <= lastDay) {
                        RelativeLayout group = getDateView(i, j);
                        group.setGravity(Gravity.CENTER);
                        TextView view = null;
                        //  TextView view1 = null;
                        if (group.getChildCount() > 0) {
                            view = (TextView) group.getChildAt(0);
                            view.setGravity(Gravity.CENTER);
                        } else {
                            RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                            view = new TextView(getContext());
                            view.setLayoutParams(params);
                            view.setGravity(Gravity.CENTER);
                            params.addRule(RelativeLayout.CENTER_IN_PARENT);
                            // view.setGravity(Gravity.CENTER);
                            group.addView(view);

                        }

                        dates[i][j] = format(new Date(calendarday.getYear(), calendarday.getMonth(), day));
                        view.setText(Integer.toString(day));

                        // 当天
                        if (today.getDate() == day && today.getMonth() == calendarday.getMonth() && today.getYear() == calendarday.getYear()) {
                            view.setTextColor(COLOR_TX_THIS_DAY);
                            view.setBackgroundResource(COLOR_BG_THIS_DAY);
                            // group.setBackgroundResource(COLOR_BG_THIS_DAY);
                            currentDayView = group;
                        } else {
                            view.setTextColor(COLOR_TX_THIS_MONTH_DAY);
//                          view.setBackgroundColor(Color.TRANSPARENT);
//                            group.setBackgroundResource(R.drawable.calendar_bg);
                        }
                        // 上面首先设置了一下默认的"当天"背景色，当有特殊需求时，才给当日填充背景色
                        // 设置日期背景色
                        if (dayBgColorMap.get(dates[i][j]) != null) {
                            view.setBackgroundColor(dayBgColorMap.get(dates[i][j]));
                        }

                        //设置周末日历颜色  周6 周日  文字颜色
                        Date tempDate = new Date(calendarYear - 1900, calendarMonth, day);
                        int tempWeekday = tempDate.getDay();
                        if (tempWeekday == 0 || tempWeekday == 6) {  //周末 设置文字颜色
                            view.setTextColor(COLOR_TX_OTHER_MONTH_DAY);
                        }
                        // 设置标记
                        setMarker(group, i, j);
                        day++;
                        // 下个月
                    } else {
                        if (calendarday.getMonth() == Calendar.DECEMBER) {
                            dates[i][j] = format(new Date(calendarday.getYear() + 1, Calendar.JANUARY, nextMonthDay));
                        } else {
                            dates[i][j] = format(new Date(calendarday.getYear(), calendarday.getMonth() + 1, nextMonthDay));
                        }
//                        view.setText(Integer.toString(nextMonthDay));
//                        view.setTextColor(COLOR_TX_OTHER_MONTH_DAY);
//                        // 设置日期背景色
//                        if (dayBgColorMap.get(dates[i][j]) != null) {
//                            view.setBackgroundColor(dayBgColorMap.get(dates[i][j]));
//                        } else {
//                            view.setBackgroundColor(Color.TRANSPARENT);
//                        }
                        // 设置标记
//                        setMarker(group, i, j);
                        nextMonthDay++;
                    }
                }
            }
        }
    }
    /**
     * onClick接口回调
     */
    public interface OnCalendarClickListener {
        void onCalendarClick(int row, int col, String dateFormat);
    }

    /**
     * 添加标记
     *
     * @param date 日期
     * @param id   bitmap res id
     */
    public void addMarks(List<String> date, int id) {
        if (date != null) {
            for (int i = 0; i < date.size(); i++) {
                marksMap.put(date.get(i), id);
            }
        }
    }

    /**
     * 移除日历上的标记
     */
    public void removeMark(Date date) {
        removeMark(format(date));
    }

    /**
     * 移除日历上的标记
     */
    public void removeMark(String date) {
        marksMap.remove(date);
        setCalendarDate();
    }

    /**
     * 移除日历上的所有标记
     */
    public void removeAllMarks() {
        marksMap.clear();
        setCalendarDate();
    }

    /**
     * 设置日历具体某个日期的背景色
     *
     * @param date
     * @param color
     */
    public void setCalendarDayBgColor(Date date, int color) {
        setCalendarDayBgColor(format(date), color);
    }

    /**
     * 设置日历具体某个日期的背景色
     *
     * @param date
     * @param color
     */
    void setCalendarDayBgColor(String date, int color) {
        dayBgColorMap.put(date, color);
        setCalendarDate();
    }

    /**
     * 设置日历一组日期的背景色
     *
     * @param date
     * @param color
     */
    public void setCalendarDaysBgColor(List<String> date, int color) {
        for (int i = 0; i < date.size(); i++) {
            dayBgColorMap.put(date.get(i), color);
        }
        setCalendarDate();
    }

    /**
     * 设置日历一组日期的背景色
     *
     * @param date
     * @param color
     */
    public void setCalendarDayBgColor(String[] date, int color) {
        for (int i = 0; i < date.length; i++) {
            dayBgColorMap.put(date[i], color);
        }
        setCalendarDate();
    }

    /**
     * 移除日历具体某个日期的背景色
     *
     * @param date
     * @param
     */
    public void removeCalendarDayBgColor(Date date) {
        removeCalendarDayBgColor(format(date));
    }

    /**
     * 移除日历具体某个日期的背景色
     *
     * @param date
     * @param
     */
    public void removeCalendarDayBgColor(String date) {
        dayBgColorMap.remove(date);
        setCalendarDate();
    }

    /**
     * 移除日历具体某个日期的背景色
     *
     * @param date
     * @param
     */
    public void removeAllBgColor(String date) {
        dayBgColorMap.clear();
        setCalendarDate();
    }

    /**
     * 根据行列号获得包装每一个日子的LinearLayout
     *
     * @param row
     * @param col
     * @return
     */
    public String getDate(int row, int col) {
        return dates[row][col];
    }

    /**
     * 某天是否被标记了
     *
     * @param
     * @param
     * @return
     */
    public boolean hasMarked(String date) {
        return marksMap.get(date) == null ? false : true;
    }

    /**
     * 清除所有标记以及背景
     */
    public void clearAll() {
        marksMap.clear();
        dayBgColorMap.clear();
    }

    /**
     * 设置标记
     *
     * @param group
     * @param i
     * @param j
     */
    private void setMarker(RelativeLayout group, int i, int j) {
        int childCount = group.getChildCount();
        if (marksMap.get(dates[i][j]) != null) {
            if (childCount < 2) {
                RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
                params.addRule(RelativeLayout.CENTER_IN_PARENT);
                ImageView markView = new ImageView(getContext());
                markView.setImageResource(marksMap.get(dates[i][j]));
                markView.setLayoutParams(params);
                group.addView(markView);  //添加标记
            }
        } else {
            if (childCount > 1) {
                group.removeView(group.getChildAt(1));
            }
        }

    }

    /**
     * 计算某年某月有多少天
     *
     * @param year
     * @param month
     * @return
     */
    private int getDateNum(int year, int month) {
        Calendar time = Calendar.getInstance();
        time.clear();
        time.set(Calendar.YEAR, year + 1900);
        time.set(Calendar.MONTH, month);
        return time.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 根据行列号获得包装每一个日子的LinearLayout
     *
     * @param row
     * @param col
     * @return
     */
    private RelativeLayout getDateView(int row, int col) {
        return (RelativeLayout) ((LinearLayout) ((LinearLayout) currentCalendar.getChildAt(0)).getChildAt(row)).getChildAt(col);
    }

    /**
     * 将Date转化成字符串->2013-3-3
     */
    private String format(Date d) {
        return addZero(d.getYear() + 1900, 4) + "-" + addZero(d.getMonth() + 1, 2) + "-" + addZero(d.getDate(), 2);
    }

    // 2或4
    private static String addZero(int i, int count) {
        if (count == 2) {
            if (i < 10) {
                return "0" + i;
            }
        } else if (count == 4) {
            if (i < 10) {
                return "000" + i;
            } else if (i < 100 && i > 10) {
                return "00" + i;
            } else if (i < 1000 && i > 100) {
                return "0" + i;
            }
        }
        return "" + i;
    }

    public void setOnCalendarClickListener(OnCalendarClickListener onCalendarClickListener) {
        this.onCalendarClickListener = onCalendarClickListener;
    }
}